home *** CD-ROM | disk | FTP | other *** search
- /*---------------------------------------------------------------------------
- * GREP.C a generalized regular expression parser
- *
- *
- * Copyright (c) 1984 Allen Holub
- * Copyright (c) 1984 Software Engineering Consultants
- * P.O. Box 5679
- * Berkeley, CA. 94705
- *
- * All rights reserved.
- *
- * This program may be copied for personal, non-commmercial use
- * only, provided that this copyright notice is included in all
- * copies and that this program is not modified in any way.
- * Copying for any other use without previously obtaining the
- * written permission of the author is prohibited.
- *
- *---------------------------------------------------------------------------
- */
-
- /*
- * The algorithm used here is essentially the algorithm in
- * Software Tools in Pascal (pp 145f.). Though the routines have
- * been changed somewhat to put them into good 'C'.
- *
- * This program is a healthy subset of the UNIX program of the same
- * name. The differences are as follows:
- *
- * - the -s, -x, and -b options are not supported.
- * - the meta-characters ()+? are not supported.
- *
- * usage is:
- * grep [-vclnhyef] [expression] files ...
- *
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <malloc.h>
- #include <string.h>
- #include "tools.h"
-
- #define MAXLINE 128 /* Maximum size of an input line */
-
- #define MAX_EXPR 64 /* Maximum number of regular expressions
- * seperated by newlines or | allowed
- */
- /* The following global flags are true if a switch was set
- * on the command line, false otherwise.
- */
-
- int vflag, yflag, cflag, lflag, nflag, hflag, fflag;
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- int i, j, linenum, count;
- int line[MAXLINE];
- int numfiles;
- FILE *stream;
- int exprc;
-
- TOKEN *exprv[MAX_EXPR];
-
- i = 1;
-
- if (argc < 2)
- abort(pr_usage(1));
-
- if (*argv[i] == '-') /* command line switches ? */
- {
- expand_sw (argv[i++]);
-
- if ( i == argc )
- abort(pr_usage(1));
- }
-
- /* Pattern string */
-
- if ((exprc = get_expr(exprv, MAX_EXPR, &argv[i++])) == 0)
- abort (pr_usage(2));
-
- numfiles = argc - i; /* number of files left to process */
-
- fprintf(stderr," \n"); /* opening message */
- do
- {
- if (numfiles)
- {
- stream = fopen(argv[i],"r");
- if (stream == NULL)
- {
- fprintf(stderr,"Can't open %s\n", argv[i]);
- continue;
- }
- }
- else
- stream = stdin;
-
- count = 0;
- linenum = 1;
-
- while (fgets(line, MAXLINE, stream))
- {
- if (yflag) /* MSC routine instead of */
- strupr(line); /* stoupper in tools.c */
-
- for (j = exprc; --j >= 0;)
- {
- if (matchs(line,exprv[j]))
- {
- count++;
- pr_match(linenum,line,argv[i],1,numfiles);
- }
- else pr_match(linenum,line,argv[i],0,numfiles);
- linenum++;
- }
- if (lflag && count) break;
- }
- pr_count(numfiles,argv[i],count);
- fclose(stream);
- } while (++i < argc);
- abort();
- }
-
- /* ----------------------------------------------------------------------- */
-
- pr_count (fcount,fname,count)
- int fcount, count;
- char *fname;
- {
- if (!cflag)
- return;
- if (fcount > 1)
- printf("%-12s: ",fname);
- printf("%d\n", count);
- }
-
- /* ----------------------------------------------------------------------- */
-
- pr_match (linenum, line, fname, match, numfiles)
- int linenum, match, numfiles;
- char *line, *fname;
- {
- char buf[80];
-
- if (cflag)
- return;
- if ((vflag && !match) || (!vflag && match))
- {
- if (!hflag && ((numfiles > 1) || lflag))
- printf("%s%s",fname,lflag ? "\n" : ":" );
- if (nflag)
- printf("%03d:",linenum);
- if (!lflag)
- printf("%s",line);
- }
- }
-
- /* ----------------------------------------------------------------------- */
-
- pr_usage (num)
- int num;
- {
- #ifdef DEBUG
- fprintf(stderr,"%d ", num);
- #endif
- fprintf(stderr,"usage: grep [-cefhlnvy] [expression] <files...>\n");
- }
-
- /* ----------------------------------------------------------------------- */
-
- abort()
- {
- exit();
- }
-
- /* ----------------------------------------------------------------------- */
-
- expand_sw(str)
- char *str;
- {
- vflag = 0;
- cflag = 0;
- lflag = 0;
- nflag = 0;
- hflag = 0;
- fflag = 0;
- yflag = 0;
-
- while (*str)
- {
- switch (toupper(*str))
- {
- case '-':
- case 'E':
- break;
- case 'C':
- cflag = 1;
- break;
- case 'F':
- fflag = 1;
- break;
- case 'H':
- hflag = 1;
- break;
- case 'L':
- lflag = 1;
- break;
- case 'N':
- nflag = 1;
- break;
- case 'V':
- vflag = 1;
- break;
- case 'Y':
- yflag = 1;
- break;
- default:
- pr_usage(3);
- abort();
- break;
- }
- str++;
- }
- }
-
- /* ----------------------------------------------------------------------- */
-
- int do_or( lp, expr, max )
- char *lp;
- TOKEN **expr;
- int max;
- {
- int found;
- TOKEN *pat;
- char *op;
-
- found = 0;
-
- /*
- * Extract regular expressions seperated by OR_SYM's from
- * lp and put them into expr. Extract only up to max
- * expressions. If yflag is true map string to uppercase first
- */
-
-
- if (yflag)
- strupr(lp);
-
- while (op = in_string(OR_SYM, lp))
- {
- if (found <= max && (pat = makepat(lp,OR_SYM)))
- {
- *expr++ = pat;
- found++;
- }
- lp = ++op;
- if (pat == 0)
- goto fatal_err;
- }
-
- if (found <= max && (pat = makepat(lp,OR_SYM)))
- {
- found++;
- *expr = pat;
- }
-
- if (pat == 0)
- {
- fatal_err:
- printf("Illegal expression\n");
- exit();
- }
- return (found);
- }
-
- /* ----------------------------------------------------------------------- */
-
- get_expr (expr, max, defexpr)
- TOKEN *expr[];
- int max;
- char **defexpr;
- {
- FILE *stream;
- int count;
- char line[MAXLINE];
-
- #ifdef DEBUG
- int i;
- #endif
- /* Get regular expressions seperated by | or newlines either
- * out of a file or off the command line depending on whether
- * the -f flag is set. The expressions are converted into
- * pattern templates and pointers to the templates are put into
- * the array expr[] (which works similar to argv).
- *
- * Return the number of expressions found (which can be used in
- * a similar fashion to argc).
- */
-
- count = 0;
-
- if (fflag)
- {
- if ((stream = fopen(*defexpr, "r")) == NULL )
- {
- fprintf (stderr, "Can't open %s\n", *defexpr);
- abort();
- }
-
- while ((max - count) && fgets (line,MAXLINE,stream))
- count+=do_or(line,&expr[count],max-count);
-
- fclose(stream);
- }
- else
- if(count+=do_or(*defexpr,&expr[count],max-count)) *defexpr = " ";
- #ifdef DEBUG
- for (i = count; --i >= 0 ;)
- {
- pr_tok (expr[1]);
- printf("------------------------------------\n");
- }
- #endif
- return (count);
- }
-
-
-